laravel5.1 基于redis实现任务队列
1、服务器配置redis
以ubuntu为例:
1、安装redis
$ sudo apt-get install redis-server
安装完成后可以使用以下命令查看redis服务是否启动
$ ps aux | grep redis
如果没有,则输入
$ sudo service redis-server start
启动后,使用
$ redis-cli
进入redis命令行,可以用以下命令行测试存储
$ set test "hello word"
$ get test
2、配置redis
配置远程登录,默认redis是不允许远程登录的,需要我们配置,
==但如果应用服务器和redis安装在同个服务器中,则不需要做这一步。==
#编辑redis配置文件
$ sudo vi /etc/redis/redis.conf
#注释掉下面这一行。
# bind 127.0.0.1
配置密码登录
#编辑redis配置文件
$ sudo vi /etc/redis/redis.conf
#找到下面这一行并去除注释
# requirepass foobared #未修改之前
#修改之后,123456是设置的redis密码
requirepass 123456
3、重启redis
$ sudo service redis-server restart
# 或者可以手动杀掉进程,再开启
$ sudo killall redis-server
$ sudo redis-server /etc/redis/redis.conf
可以在别的客户端中测试连接(客户端已经配置好redis)
# -h接redis服务器地址,-p端口号,-a密码
$ redis-cli -h 192.168.1.188 -p 6379 -a 123456
2、应用服务器安装php redis扩展
注意:如果redis使用频率不高,只是该项目使用,可以不用安装php的redis扩展,直接在对应的laravel项目安装predis扩展包(从开发编码实现那步开始)
==由于测试时我们以自己的电脑当应用服务器,以windows为例:==
(1)redis的php扩展下载地址:
http://windows.php.net/downlo...
根据自己的php版本和系统版本,下载对应的扩展包,解压
文件“php_redis-2.2.5-5.5-ts-vc11-x64.zip”是php5.5版本的。
(2)将解压文件中的php_redis.dll放到php的扩展目录ext下。
(3)在apache的php.ini配置文件下加上extension=php_redis.dll
(4)重启apache。
查看phpinfo是否有redis的扩展,如果有,则说明php-redis安装成功。
==以ubuntu为例==
$ sudo apt-get install php5-redis
重启apache
$ sudo /etc/init.d/apache2 restart
查看phpinfo是否有redis的扩展,如果有,则说明php5-redis安装成功。
3、开发编码实现
(1)需要安装predis扩展包
$ composer require "predis/predis:~1.0"
php artisan config:cache
(2)配置文件中.env中需要增加队列驱动的配置
QUEUE_DRIVER=redis
REDIS_HOST=192.168.1.188
(3)config/database.php配置redis的连接参数
'redis' => [
'cluster' => false,
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'port' => 6379,
'database' => 0,
'password' => env('REDIS_PASSWORD', '123456')
],
],
(4)在appJobs中创建任务类,当队列处理该任务时执行的handle方法。
这里以我们实际代码为例:
<?php
namespace App\Jobs;
use App\Jobs\Job;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Classes\LogisticApi\LogisticSdk\alibaba\AlibabaClient;
use Illuminate\Support\Facades\Redis;
/**
* 阿里巴巴无忧物流创建线上发货createWarehouseOrder后,
* 国际物流单号不是实时返回,需要间隔1-2分钟调用查询接口进行查询
* 此任务主要进行阿里getOnlineLogisticsInfo接口的查询
*/
class AligetOnlineLogisticsInfo extends Job implements SelfHandling, ShouldQueue
{
use InteractsWithQueue, SerializesModels;
/**
* 订单ID
* @var string
*/
protected $order_id;
/**
* api 账号信息
* @var array
*/
protected $api_account;
/**
* Create a new job instance.
*
* @param string $order_id 订单ID
* @param string $seller_id
*
* @return void
*/
public function __construct($order_id, $api_account){
$this->order_id = $order_id;
$this->api_account = $api_account;
}
/**
* Execute the job.
* 获取getOnlineLogisticsInfo物流信息
*
* @return void
*/
public function handle(){
$alibaba_client = new AlibabaClient($this->api_account);
$response = $alibaba_client->getOnlineLogisticsInfo(['orderId' => $this->order_id]);
print_r($response);
//TODO 抓取失败后的处理,后续根据业务需求来处理
}
}
(5)推送任务到队列。
使用了DispatchesJobs trait。该trait提供了一些允许你方便推送任务到队列的方法,例如dispatch方法。可以为任务指定队列,也可以延迟任务。
以我们实际业务为例:
namespace App\Classes\LogisticApi;
use App\Classes\LogisticApi\LogisticTrackingAbstract;
use App\Classes\LogisticApi\LogisticSdk\alibaba\AlibabaClient;
use App\Models\Erp_aliexpress_order_master;
use App\Models\Erp_aliexpress_order_slave;
use App\Models\Erp_logistics_setting;
use App\Models\Erp_aliexpress_token;
use Illuminate\Foundation\Bus\DispatchesJobs;
use App\Jobs\AligetOnlineLogisticsInfo;
/**
* ocs物流对接
*/
class logisticTrackingWuyou extends LogisticTrackingAbstract {
use DispatchesJobs;
/**
*
*/
public function __construct(){
}
/**
* 获取tracking数据
*
* @param array $api_data 订单数据,可以是订单号之类的
* @param array $api_param 接口参数数据
* @param string $save_path 保存运单图片的路径
*
* @return array tracking
*/
public function getTracking(array $api_data, array $api_param, $save_path){
//得到订单信息
$order = $this->getOrder($api_data['order_id']);
//得到对应的订单账号信息
$api_account = $this->getApiAccountInfo($order['seller_id']);
$alibaba_client = new AlibabaClient($api_account);
$params = $this->setCreateWarehouseOrderApiParams($order, $alibaba_client);
if(isset($seller_address->error_code)){
return $params;
}
$response = $alibaba_client->createWarehouseOrder($params);
//成功了,推送队列任务获取getOnlineLogisticsInfo国际物流,
//国际物流返回不是实时返回,需要等待1-2分钟
if(true == $response->success){
//推入getOnlineLogisticsInfo队列并延迟120秒执行
$job = (new AligetOnlineLogisticsInfo($api_data['order_id'], $api_account))->delay(120);
$this->dispatch($job);
}
return $response;
}
}
==注意,由于我们没有正式的业务情景测试,所以使用单元测试,在测试之前,需要配置好单元测试的队列驱动,在phpunit.xml中,注意
以下QUEUE_DRIVER,需要将其改为redis,或者删掉。==
<env name="QUEUE_DRIVER" value="sync"/>
4、运行队列监听器
(1)应用服务器监听
如果之前有 php artisan config:cache 缓存配置,最好先把配置缓存清除:php artisan config:clear。
测试过程中,可以使用 ==php artisan queue:listen==进行监听。
线上可以使用 ==php artisan queue:work --daemon==
详细的监听方式可以查看:http://laravelacademy.org/pos...
(2)redis服务器监听
redis-cli连接redis后,可以使用==monitor==查看队列情况。
具体可以参考:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。